package com.hjy.upload;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.hjy.upload.pojo.DepositAccountBo;
import com.hjy.upload.pojo.UploadBodyBo;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author yhan219
 * @date 2022-05-23 10:27:29
 */
public class UploadDemo {

    private static final String ORG_KEY = "gnxeszjtokyuiwprmcbfhvladq";
    private static final String ORG_SECRET = "kTM5diFAGfu8z1JsuDILHuQHTyanRFTB";

    private static final String BASE_URL = "http://218.63.232.8:86/";
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    private static final ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        simpleModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        objectMapper.registerModule(simpleModule);
    }

    private static String getSign(String nonce, String timestamp, String data) {
        String step1 =
                "data=" + data +
                        "&nonce=" + nonce +
                        "&orgKey=" + ORG_KEY +
                        "&timestamp=" + timestamp;
        System.out.println("签名第1步结果:" + step1);
        String step2 = ORG_SECRET + step1 + ORG_SECRET;
        System.out.println("签名第2步结果:" + step2);
        String step3 = step2.toLowerCase();
        System.out.println("签名第3步结果:" + step3);
        String s = SecureUtil.md5(step3);
        System.out.println("签名第4步结果:" + s);
        return s;
    }

    private static <T> String getData(T data) {
        AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, ORG_SECRET.getBytes(), ORG_SECRET.substring(0, 16).getBytes());
        byte[] encrypt = new byte[0];
        try {
            encrypt = aes.encrypt(objectMapper.writeValueAsString(data));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return Base64.encode(encrypt);
    }

    private static <T> String getData(List<T> data) {
        AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, ORG_SECRET.getBytes(), ORG_SECRET.substring(0, 16).getBytes());
        byte[] encrypt = new byte[0];
        try {
            encrypt = aes.encrypt(objectMapper.writeValueAsString(data));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return Base64.encode(encrypt);
    }


    public static <T> void doUpload(List<T> uploadInfo, String url) throws Exception {
        LocalDateTime now = LocalDateTime.now();
        String timestamp = now.format(TIME_FORMATTER);
//        String timestamp = "20220519111111";
        String nonce = UUID.randomUUID().toString();
//        String nonce = "3EEEBE729BDF4A79AC6739D1BE487009";
        System.out.println("orgKey:" + ORG_KEY);
        System.out.println("orgSecret:" + ORG_SECRET);
        System.out.println("timestamp:" + timestamp);
        System.out.println("nonce:" + nonce);
        String data = getData(uploadInfo);
        String sign = getSign(nonce, timestamp, data);
        UploadBodyBo uploadBodyParam = new UploadBodyBo(ORG_KEY, nonce, timestamp, sign, data);
        System.out.println("sign:" + sign);
        System.out.println("data明文:" + objectMapper.writeValueAsString(uploadInfo));
        System.out.println("data密文:" + data);
        String uploadBody = objectMapper.writeValueAsString(uploadBodyParam);
        System.out.println("请求数据:" + uploadBody);
        String body = HttpRequest.post(BASE_URL + url)
                .body(uploadBody)
                .execute()
                .body();
        System.out.println("上传结果: " + body);
    }

    public static void main(String[] args) throws Exception {

        List<Object> data = new ArrayList<>();
        Map<Object, Object> map = new HashMap<>();
        map.put("hello", "world");
        data.add(map);
        doUpload(data, UrlConst.ECHO);

        String str = "[\n" +
                "    {\n" +
                "        \"mainAccountCode\": \"1234\",\n" +
                "        \"accountCode\": \"2234-1002\",\n" +
                "        \"accountName\": \"子账户003\",\n" +
                "        \"balance\": \"17.76\",\n" +
                "        \"enterpriseName\": \"子账户003\",\n" +
                "        \"enterpriseCode\": \"123456\",\n" +
                "        \"bankCode\": \"223456\",\n" +
                "        \"bankName\": \"测试\",\n" +
                "        \"projectName\": \"推送测试项目\",\n" +
                "        \"specialStatus\": 0,\n" +
                "        \"remark\": \" \",\n" +
                "        \"createDate\": \"2019-03-27 15:20:22\",\n" +
                "        \"updateDate\": \"2023-04-14 15:20:22\"\n" +
                "    }" +
                "]";


        List<DepositAccountBo> list = JSONUtil.toList(str, DepositAccountBo.class);

        doUpload(list, UrlConst.DEPOSIT_ACCOUNT);


    }



}